<template>
    <div class="content" :style="{width: 153*lines + 'px'}">
        行数：
        <input type="text" v-model="lines" @input="generateData"/>
        <button @click="generateData">新游戏</button>
        <div class="line" v-for="(i, iIndex) in data" :key="iIndex">
            <div class="item"
                 v-for="(j, jIndex) in i"
                 :key="jIndex"
                 :class="{n2: j === 2,n4: j===4,n8:j===8,n16:j===16,n32:j===32,n64:j===64,n128:j===128,n256: j===256,n512: j===512,n1024:j===1024,n2048: j===2048}">
                {{j || ''}}
            </div>
        </div>
    </div>
</template>

<script lang="ts">
    import {Component, Vue} from "vue-property-decorator"

    @Component
    export default class HelloWorld extends Vue {

        /*
        * Math.round(Math.random())  随机数 0或1
        * Math.floor(Math.random()*n) 随机数0到n-1
        * */
        // 所有数字
        data: Array<Array<number>> = []
        // 所有空白位置下标  0 表示 data[0][0]  5表示data[1][1]
        emptyPosition: Array<number> = []
        lines = 6

        created() {
            this.generateData()
            let _this = this
            /*
			* keycode 37 = Left
			  keycode 38 = Up
			  keycode 39 = Right
			  keycode 40 = Down
			* */
            document.onkeydown = function (e: any) {
                let key = (window.event as any).keyCode
                let moved = false
                switch (key) {
                    case 37:
                        _this.actionLeft()
                        e.preventDefault()
                        break
                    case 38:
                        _this.actionUp()
                        e.preventDefault()
                        break
                    case 39:
                        _this.actionRight()
                        e.preventDefault()
                        break
                    case 40:
                        _this.actionDown()
                        e.preventDefault()
                        break
                }
                if (_this.emptyPosition.length === 0) {

                } else {
                    _this.generateNewNumber()
                }
            }
        }

        generateData() {
            this.data = []
            this.emptyPosition = []
            for (let i = 0; i < this.lines; i++) {
                let arr = []
                for (let j = 0; j < this.lines; j++) {
                    this.emptyPosition.push(i * this.lines + j)
                    arr.push(0)
                }
                this.data.push(arr)
            }
            this.generateNewNumber()
            this.generateNewNumber()
        }

        generateNewNumber() {
            let position = Math.floor(Math.random() * this.emptyPosition.length)
            let num = Math.round(Math.random()) === 0 ? 2 : 4
            this.assignment(position, num)
            this.generateEmptyPosition()
        }

        /*
		*  position 为在 emptyPosition 集合里的下标
		*  num 为要填入的数
		* */
        private assignment(position: number, num: number) {
            let dataPosition = this.emptyPosition[position]
            let dataLine = parseInt(String(dataPosition / this.lines))
            let linePosition = Math.round(dataPosition % this.lines)
            this.data[dataLine][linePosition] = num
            console.log(position, dataLine, linePosition, num)
        }

        private actionLeft() {
            let data: Array<Array<number>> = Object.assign([], this.data)
            let moved = false
            for (let i in data) {
                let temp = 0
                let index = 0
                for (let j in data[i]) {
                    //当前位置不为 0
                    if (data[i][j]) {
                        // 临时值为0  赋值给临时值
                        if (temp === 0) {
                            temp = data[i][j]
                            data[i][j] = 0
                        } else if (temp === data[i][j]) { //临时值不为0 判断是否和当前值相同 相同相加并赋值给index位
                            data[i][index] = temp * 2
                            data[i][j] = 0
                            temp = 0
                            index++
                        } else { //临时值不为0 且和当前值不同 临时值赋值给 index 当前值赋值给临时值
                            data[i][index] = temp
                            temp = data[i][j]
                            data[i][j] = 0
                            index++
                        }
                    }
                }
                if (temp) {
                    data[i][index] = temp
                }
            }
            this.data = data
            this.generateEmptyPosition()
        }

        private actionUp() {
            let data: Array<Array<number>> = Object.assign([], this.data)
            for (let i in data) {
                let temp = 0
                let index = 0
                for (let j in data) {
                    if (data[j][i]) {
                        if (temp === 0) {
                            temp = data[j][i]
                            data[j][i] = 0
                        } else if (temp === data[j][i]) {
                            data[index][i] = temp * 2
                            data[j][i] = 0
                            temp = 0
                            index++
                        } else {
                            data[index][i] = temp
                            temp = data[j][i]
                            data[j][i] = 0
                            index++
                        }
                    }
                }
                if (temp) {
                    data[index][i] = temp
                }
            }
            this.data = data
            this.generateEmptyPosition()
        }

        private actionRight() {
            let data: Array<Array<number>> = Object.assign([], this.data)
            for (let i in data) {
                let temp = 0
                let index = this.lines - 1
                for (let j = this.lines - 1; j >= 0; j--) {
                    //当前位置不为 0
                    if (data[i][j]) {
                        if (temp === 0) {
                            temp = data[i][j]
                            data[i][j] = 0
                        } else if (temp === data[i][j]) {
                            data[i][index] = temp * 2
                            temp = 0
                            data[i][j] = 0
                            index--
                        } else {
                            data[i][index] = temp
                            temp = data[i][j]
                            data[i][j] = 0
                            index--
                        }
                    }
                }
                if (temp) {
                    data[i][index] = temp
                }
            }
            this.data = data
            this.generateEmptyPosition()
        }

        private actionDown() {
            let data: Array<Array<number>> = Object.assign([], this.data)
            for (let i in data) {
                let temp = 0
                let index = this.lines - 1
                for (let j = this.lines - 1; j >= 0; j--) {
                    if (data[j][i]) {
                        if (temp === 0) {
                            temp = data[j][i]
                            data[j][i] = 0
                        } else if (temp === data[j][i]) {
                            data[index][i] = temp * 2
                            data[j][i] = 0
                            temp = 0
                            index--
                        } else {
                            data[index][i] = temp
                            temp = data[j][i]
                            data[j][i] = 0
                            index--
                        }
                    }
                }
                if (temp) {
                    data[index][i] = temp
                }
            }
            this.data = data
            this.generateEmptyPosition()
        }

        private generateEmptyPosition() {
            this.emptyPosition = []
            this.data.forEach((i: any, iIndex: number) => {
                i.forEach((j: any, jIndex: number) => {
                    if (!j) {
                        this.emptyPosition.push(iIndex * this.lines + jIndex)
                    }
                })
            })
        }


    }
</script>

<style scoped>
    .n2 {
        background: rgb(238, 238, 218);
    }

    .n4 {
        background: rgb(237, 224, 200);
    }

    .n8 {
        background: rgb(242, 177, 121);
    }

    .n16 {
        background: rgb(245, 149, 99);
    }

    .n32 {
        background: rgb(246, 124, 95);
    }

    .n64 {
        background: rgb(246, 94, 59);
    }

    .n128 {
        background: rgb(237, 207, 114);
    }

    .n256 {
        background: rgb(237, 204, 97);
    }

    .n512 {
        background: rgb(237, 200, 80);
    }

    .n1024 {
        background: rgb(237, 197, 63);
    }

    .n2048 {
        background: red;
    }

    .content {
        margin: 50px auto 0;
    }

    table {
        border: 1px;
    }

    td {
        width: 150px;
        background: rgb(205, 193, 180);
        height: 150px;
        padding: 0;
        font-size: 35px;
        color: darkolivegreen;
    }

    .line {
        height: 150px;
        margin-bottom: 3px;
    }

    .item {
        width: 150px;
        height: 150px;
        line-height: 150px;
        float: left;
        background: rgb(205, 193, 180);
        margin-right: 3px;
        font-size: 35px;
        text-align: center;
        color: darkolivegreen;
    }
</style>
